home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok59.lha
/
AmokEd_V1.02b
/
txt
/
EdMovement.mod
< prev
next >
Wrap
Text File
|
1993-08-15
|
28KB
|
983 lines
(*************************************************************************
:Program. EdMovement.mod
:Contents. Cursor-Movement for AmokEd
:Author. Hartmut Goebel
:Language. Oberon
:Translator. AmigaOberon V2.00
:History. V0.1, 03 Dec 1990 Hartmut Goebel
:History. V1.0, 14 Apr 1991 Hartmut Goebel [hG]
:History. V1.0b 24 Apr 1991 [hG] -Bugs: doReturn, doRepeat, doIf
:History. V1.0c 26 Apr 1991 [hG] ^doJoin, _etwas_ optimiert
:History. V1.1 12 Sep 1991 [hG] + doReformat
:Date. 17 Oct 1991 21:16:35
*************************************************************************)
MODULE EdMovement;
(* $Debug- *)
IMPORT
EdGadgets,
e : Exec,
edB: EdBlocks,
edD: EdDisplay,
edE: EdErrors,
edG: EdGlobalVars,
edL: EdLowLevel,
g : Graphics,
lst: EdLists,
str: Strings,
sys: SYSTEM;
CONST
(* Flags für einzelne Kommandos *)
pageSet* = 0; (* PageSet od. PageUp/Down *)
pageUp* = 1; (* PageUp od. PageDown *)
rfmtParag* = 0;
LineTooLong = "Line too long!";
LineMarked = "Line marked";
PingOutOfRange = "ping: out of range";
PongRangeErrorOrNothingMarked = "pong: range error or nothing marked";
VAR
PagePctg: INTEGER;
(*--------------------------------------------------------------------------*)
PROCEDURE doToMouse*;
BEGIN
edD.TextPosition((edG.Mx-edG.XBase) DIV edG.XSize,
(edG.My-edG.YBase) DIV edG.YSize);
END doToMouse;
(*--------------------------------------------------------------------------*)
PROCEDURE^ doReformat*; (* Forward, wird in doDel und doBS gebraucht *)
(*--------------------------------------------------------------------------*)
PROCEDURE doUp*;
BEGIN
IF edG.Text.line # 0 THEN
edD.PutBackLine;
DEC(edG.Text.line);
edG.Text.actLinePtr := edG.Text.actLinePtr.prev(edG.Line);
edD.TextLoad;
IF (edG.Text.line < edG.Text.topLine) THEN
edG.Text.topLinePtr := edG.Text.actLinePtr;
DEC(edG.Text.topLine);
IF edG.NoScreenUpdate = 0 THEN
edD.FastScrollRaster(0,-edG.YSize,edD.Col(0),edD.Row(0),
edD.Col(edG.Columns)-1,edD.Row(edG.Rows)-1);
edD.TextDisplaySeg(0,1);
EdGadgets.SetPropKnob;
END;
END;
ELSE
edG.Rc := edE.cmdFailed;
END;
END doUp;
PROCEDURE doDown*;
BEGIN
IF edG.Text.actLinePtr # edG.Text.lineList.tail THEN
edD.PutBackLine;
INC(edG.Text.line);
edG.Text.actLinePtr := edG.Text.actLinePtr.next(edG.Line);
edD.TextLoad;
IF (edG.Text.line-edG.Text.topLine >= edG.Rows) THEN
edG.Text.topLinePtr := edG.Text.topLinePtr.next(edG.Line);
INC(edG.Text.topLine);
IF edG.NoScreenUpdate = 0 THEN
edD.FastScrollRaster(0,edG.YSize,edD.Col(0),edD.Row(0),
edD.Col(edG.Columns)-1,edD.Row(edG.Rows)-1);
edD.TextDisplaySeg(edG.Rows-1,1);
EdGadgets.SetPropKnob;
END;
END;
ELSE
edG.Rc := edE.cmdFailed;
END;
END doDown;
PROCEDURE doScrollUp*;
BEGIN
IF edG.Text.topLine > 0 THEN
IF edG.NoScreenUpdate = 0 THEN
edD.PutBackLine;
edD.FastScrollRaster(0,-edG.YSize,edD.Col(0),edD.Row(0),
edD.Col(edG.Columns)-1,edD.Row(edG.Rows)-1);
edG.Text.topLinePtr := edG.Text.topLinePtr.prev(edG.Line);
edG.Text.actLinePtr := edG.Text.actLinePtr.prev(edG.Line);
DEC(edG.Text.topLine);
DEC(edG.Text.line);
edD.TextLoad;
edD.TextDisplaySeg(0,1);
EdGadgets.SetPropKnob;
END;
ELSE
edG.Rc := edE.cmdFailed;
END;
END doScrollUp;
PROCEDURE doScrollDown*;
BEGIN
IF edG.Text.topLine + edG.Rows < edG.Text.numberOfLines THEN
IF edG.NoScreenUpdate = 0 THEN
edD.PutBackLine;
edD.FastScrollRaster(0,edG.YSize,edD.Col(0),edD.Row(0),
edD.Col(edG.Columns)-1,edD.Row(edG.Rows)-1);
edG.Text.topLinePtr := edG.Text.topLinePtr.next(edG.Line);
edG.Text.actLinePtr := edG.Text.actLinePtr.next(edG.Line);
INC(edG.Text.topLine);
INC(edG.Text.line);
edD.TextLoad;
edD.TextDisplaySeg(edG.Rows-1,1);
EdGadgets.SetPropKnob;
END;
ELSE
edG.Rc := edE.cmdFailed;
END;
END doScrollDown;
PROCEDURE doDownAdd*;
VAR
newLine : edG.LinePtr;
BEGIN
IF edG.Text.line+1 = edG.Text.numberOfLines THEN
edL.NewLine(newLine,edG.ChunkSize);
IF newLine # NIL THEN
lst.AddTail(edG.Text.lineList,newLine);
INC(edG.Text.numberOfLines);
INCL(edG.Text.status,edG.modified);
END;
END;
doDown;
END doDownAdd;
(*--------------------------------------------------------------------------*)
PROCEDURE doTop*;
BEGIN
edD.PutBackLine;
edG.Text.line := 0;
edG.Text.actLinePtr :=edG.Text.lineList.head(edG.Line);
edD.TextLoad;
edD.TextSync;
EdGadgets.SetPropKnob;
END doTop;
PROCEDURE doBottom*;
BEGIN
edD.PutBackLine;
edG.Text.line := edG.Text.numberOfLines-1;
edG.Text.actLinePtr :=edG.Text.lineList.tail(edG.Line);
(*edG.Text.topLine := edG.Text.line-edG.Rows;
IF edG.Text.topLine < 0 THEN
edG.Text.topLine := 0; END;*)
edD.TextLoad;
edD.TextSync;
EdGadgets.SetPropKnob;
END doBottom;
PROCEDURE doScreenTop*;
BEGIN
edD.PutBackLine;
edG.Text.line := edG.Text.topLine;
edG.Text.actLinePtr := edG.Text.topLinePtr;
edD.TextLoad;
edD.TextSync;
END doScreenTop;
PROCEDURE doScreenBottom*;
BEGIN
edD.PutBackLine;
edG.Text.line := edG.Text.topLine + edG.Rows - 1;
IF edG.Text.line >= edG.Text.numberOfLines THEN
edG.Text.line := edG.Text.numberOfLines - 1; END;
edG.Text.actLinePtr := edG.Text.topLinePtr;
lst.GoForwardNil(edG.Text.actLinePtr,edG.Text.line-edG.Text.topLine);
edD.TextLoad;
edD.TextSync;
END doScreenBottom;
(*--------------------------------------------------------------------------*)
PROCEDURE doLeft*;
BEGIN
IF edG.Text.pos #0 THEN
DEC(edG.Text.pos);
IF edG.Text.pos < edG.Text.topPos THEN
edD.TextSync; END;
ELSE
edG.Rc := edE.cmdFailed;
END;
END doLeft;
PROCEDURE doRight*;
BEGIN
IF edG.Text.pos < edG.MaxLineLength-2 THEN
IF edG.Text.pos = edG.LineBufferLen THEN
edG.LineBuffer[edG.LineBufferLen] := 20X;
INC(edG.LineBufferLen);
edG.LineBuffer[edG.LineBufferLen] := 0X;
END;
INC(edG.Text.pos);
IF (edG.Text.pos-edG.Text.topPos >= edG.Columns) THEN
edD.TextSync; END;
ELSE
edG.Rc := edE.cmdFailed;
END;
END doRight;
PROCEDURE doWordLeft*;
VAR
i: INTEGER;
BEGIN
LOOP
i := edG.Text.pos;
IF i # 0 THEN
REPEAT
DEC(i);
UNTIL (i=0) OR (edL.IsAscii(edG.LineBuffer[i]));
END;
IF (edG.LineBufferLen=0) OR (edG.Text.pos=0) THEN
IF (edG.commLineMode IN edG.Status) OR (edG.Text.line = 0) THEN
EXIT;
END;
edD.PutBackLine;
edG.Text.actLinePtr := edG.Text.actLinePtr.prev(edG.Line);
DEC(edG.Text.line);
edG.Text.pos := 0; (* damit's schneller geht *)
edD.TextLoad;
edG.Text.pos := edG.LineBufferLen;
ELSE
WHILE (i#0) AND (edL.IsAscii(edG.LineBuffer[i])) DO
DEC(i); END;
IF (i#0) AND NOT (edL.IsAscii(edG.LineBuffer[i])) THEN
INC(i); END;
EXIT;
END;
END;
edG.Text.pos := i;
edD.TextSync;
END doWordLeft;
PROCEDURE doWordRight*;
VAR
i: INTEGER;
BEGIN
LOOP
i := edG.Text.pos;
IF i # edG.LineBufferLen THEN
WHILE (i<edG.LineBufferLen) AND (edL.IsAscii(edG.LineBuffer[i])) DO
INC(i); (* zum Wordende *)
END;
WHILE (i<edG.LineBufferLen) AND NOT (edL.IsAscii(edG.LineBuffer[i])) DO
INC(i); (* zum nächsten Wort *)
END;
EXIT;
ELSE
IF (edG.commLineMode IN edG.Status)
OR (edG.Text.line = edG.Text.numberOfLines -1) THEN
i := edG.Text.pos;
EXIT;
END;
edD.PutBackLine;
edG.Text.actLinePtr := edG.Text.actLinePtr.next(edG.Line);
INC(edG.Text.line);
edG.Text.pos := 0; (* wg. Auffüllen mit Spaces *)
edD.TextLoad;
IF edL.IsAscii(edG.LineBuffer[0]) THEN
i := 0;
EXIT;
END;
edG.Text.pos := 0;
END;
END;
edG.Text.pos := i;
edD.TextSync;
END doWordRight;
(*--------------------------------------------------------------------------*)
PROCEDURE doFirstColumn*;
BEGIN
edL.StripEndSpaces;
IF edG.Text.pos # 0 THEN edG.Text.pos := 0; edD.TextSync; END;
END doFirstColumn;
PROCEDURE doFirstNb*;
VAR
i: INTEGER;
BEGIN
edL.StripEndSpaces;
i := 0;
WHILE edG.LineBuffer[i] = 20X DO INC(i); END;
IF edG.LineBuffer[i] = 0X THEN i := 0; END;
edG.Text.pos := i;
edD.TextSync;
END doFirstNb;
PROCEDURE doLastColumn*;
VAR
i: INTEGER;
BEGIN
edL.StripEndSpaces;
edG.Text.pos := edG.LineBufferLen;
edD.TextSync;
END doLastColumn;
(*--------------------------------------------------------------------------*)
PROCEDURE doTab*;
VAR
n: INTEGER;
BEGIN
n := SHORT(edG.Text.tabStop-(edG.Text.pos MOD edG.Text.tabStop));
REPEAT
doRight;
DEC(n);
UNTIL n = 0;
END doTab;
PROCEDURE doBackTab*;
VAR
n: INTEGER;
BEGIN
n := SHORT(edG.Text.pos MOD edG.Text.tabStop);
IF n = 0 THEN (* genau auf Tabposition *)
n := SHORT(edG.Text.tabStop); END;
REPEAT
doLeft;
DEC(n);
UNTIL n = 0;
END doBackTab;
(*--------------------------------------------------------------------------*)
PROCEDURE doDel*;
VAR
buf : edG.StringPtr;
BEGIN
IF edG.LineBuffer[edG.Text.pos] # 0X THEN
str.Delete(edG.LineBuffer,edG.Text.pos,1);
DEC(edG.LineBufferLen);
edD.FastScrollRaster(edG.XSize,0,
edD.Col(edG.Text.pos-edG.Text.topPos),
edD.Row(SHORT(edG.Text.line-edG.Text.topLine)),
edD.Col(edG.Columns)-1,
edD.Row(SHORT(edG.Text.line-edG.Text.topLine+1))-1);
IF (edG.LineBufferLen >= edG.Text.topPos+edG.Columns) THEN
edD.SetPen(edG.Text.line);
g.Move(edG.RPort,edD.ColT(edG.Columns-1),
edD.RowT(SHORT(edG.Text.line-edG.Text.topLine)));
buf := sys.ADR(edG.LineBuffer);
INC(buf,edG.Text.topPos+edG.Columns-1);
g.Text(edG.RPort,buf^,1);
END;
IF NOT (edG.commLineMode IN edG.Status)
AND (edG.wordWrap IN edG.Text.status) THEN
edG.ArgSet := {};
doReformat;
END;
ELSE
edG.Rc := edE.cmdFailed;
END;
END doDel;
PROCEDURE doBs*;
VAR
buf : edG.StringPtr;
BEGIN
IF edG.Text.pos # 0 THEN
str.Delete(edG.LineBuffer,edG.Text.pos-1,1);
DEC(edG.Text.pos);
DEC(edG.LineBufferLen);
IF edG.Text.pos < edG.Text.topPos THEN
edD.TextSync;
ELSE
edD.FastScrollRaster(edG.XSize, 0,
edD.Col(edG.Text.pos-edG.Text.topPos),
edD.Row(SHORT(edG.Text.line-edG.Text.topLine)),edD.Col(edG.Columns)-1,
edD.Row(SHORT(edG.Text.line-edG.Text.topLine+1))-1);
IF (edG.LineBufferLen >= edG.Text.topPos+edG.Columns) THEN
edD.SetPen(edG.Text.line);
g.Move(edG.RPort,edD.ColT(edG.Columns-1),
edD.RowT(SHORT(edG.Text.line-edG.Text.topLine)));
buf := sys.ADR(edG.LineBuffer);
INC(buf,edG.Text.topPos+edG.Columns);
g.Text(edG.RPort,buf^,1);
END;
END;
IF NOT (edG.commLineMode IN edG.Status)
AND (edG.wordWrap IN edG.Text.status) THEN
edG.ArgSet := {};
doReformat;
END;
ELSE
edG.Rc := edE.cmdFailed;
END;
END doBs;
PROCEDURE doRemEOL*;
BEGIN
edG.LineBufferLen := edG.Text.pos;
edG.LineBuffer[edG.LineBufferLen] := 0X;
edD.TextRedisplayCurrentLine;
END doRemEOL;
(*----------------------------------------------------------------------*)
PROCEDURE InsertLine(newLine: edG.LinePtr; Behind: BOOLEAN);
BEGIN
edD.PutBackLine;
IF Behind THEN
lst.AddBehind(edG.Text.lineList,newLine,edG.Text.actLinePtr);
edB.HoldBlockLines(FALSE);
ELSE
lst.AddBefore(edG.Text.lineList,newLine,edG.Text.actLinePtr);
IF edG.Text.topLinePtr = edG.Text.actLinePtr THEN
edG.Text.topLinePtr := newLine; END;
edG.Text.actLinePtr := newLine;
edD.TextLoad;
DEC(edG.Text.line);
edB.HoldBlockLines(FALSE);
INC(edG.Text.line);
END;
INC(edG.Text.numberOfLines);
INCL(edG.Text.status,edG.modified);
IF edG.NoScreenUpdate = 0 THEN
g.ScrollRaster(edG.RPort,0,-edG.YSize,edD.Col(0),
edD.Row(SHORT(edG.Text.line-edG.Text.topLine)),
edD.Col(edG.Columns)-1,edD.Row(edG.Rows)-1);
edD.TextDisplaySeg(SHORT(edG.Text.line-edG.Text.topLine),2);
END;
END InsertLine;
PROCEDURE doInsLine*;
VAR
newLine: edG.LinePtr;
BEGIN
edL.NewLine(newLine,edG.ChunkSize);
IF edG.memoryFail IN edG.Status THEN
edG.Rc := edE.cmdSevere;
RETURN;
END;
InsertLine(newLine,FALSE);
END doInsLine;
PROCEDURE doUndelLine*;
VAR
newLine: edG.LinePtr;
BEGIN
IF edG.DelLinePtr = NIL THEN edG.Rc := edE.cmdFailed; RETURN END;
newLine := edL.CreateLineCopy(edG.DelLinePtr);
IF newLine=NIL THEN edG.Rc := edE.cmdSevere; RETURN END;
InsertLine(newLine,FALSE);
END doUndelLine;
PROCEDURE doDelLine*;
VAR
This: edG.LinePtr;
BEGIN
IF edG.Text.numberOfLines > 1 THEN
INCL(edG.Text.status,edG.modified);
edD.PutBackLine;
This := edG.Text.actLinePtr;
edB.HoldBlockLines(TRUE);
edG.Text.actLinePtr := edG.Text.actLinePtr.next(edG.Line);
lst.Remove(edG.Text.lineList,This);
IF edG.LineBufferLen > 0 THEN (* nur retten, wenn was drin steht *)
IF edG.DelLinePtr # NIL THEN
e.FreeMem(edG.DelLinePtr(edG.Line).string,edG.DelLinePtr(edG.Line).len);
e.FreeMem(edG.DelLinePtr,edG.LineAllocSize);
END;
edG.DelLinePtr := This;
ELSE
e.FreeMem(This(edG.Line).string,This(edG.Line).len);
e.FreeMem(This,edG.LineAllocSize);
END;
DEC(edG.Text.numberOfLines);
IF edG.Text.actLinePtr = NIL THEN (* es war die letzte Ziele *)
edG.Text.actLinePtr := edG.Text.lineList.tail(edG.Line);
DEC(edG.Text.line); (* eine Zeile vor *)
END;
edD.TextLoad;
IF edG.Text.line < edG.Text.topLine THEN
edD.TextSync;
RETURN;
ELSIF edG.Text.line = edG.Text.topLine THEN
edG.Text.topLinePtr := edG.Text.actLinePtr;
END;
IF edG.NoScreenUpdate = 0 THEN
g.ScrollRaster(edG.RPort,0,edG.YSize,edD.Col(0),
edD.Row(SHORT(edG.Text.line-edG.Text.topLine+1)),
edD.Col(edG.Columns)-1,edD.Row(edG.Rows)-1);
edD.TextRedisplayCurrentLine;
edD.TextDisplaySeg(edG.Rows-1,1);
END;
ELSE
edG.Text.pos := 0;
doRemEOL;
EXCL(edG.Text.status,edG.modified);
END;
END doDelLine;
PROCEDURE doJoin*;
VAR
i: INTEGER;
next: edG.LinePtr;
BEGIN
edL.StripEndSpaces;
i := edG.LineBufferLen;
IF (edG.Text.line+1 < edG.Text.numberOfLines)
AND (i+str.Length(next(edG.Line).string^)<edG.MaxLineLength)
THEN
next := edG.Text.actLinePtr.next(edG.Line);
IF (i # 0) AND (edG.LineBuffer[i] # 20X) THEN
edG.LineBuffer[i] := " "; edG.LineBuffer[i+1] := "\o";
END;
i := 0;
WHILE next(edG.Line).string[i] = 20X DO
INC(i); END;
IF i > 0 THEN str.Delete(next(edG.Line).string^,0,i); END;
str.Append(edG.LineBuffer,next(edG.Line).string^);
edG.LineBufferLen := str.Length(edG.LineBuffer);
edD.PutBackLine;
INC(edG.Text.line);
edB.HoldBlockLines(TRUE);
DEC(edG.Text.line);
edL.FreeLines(edG.Text.lineList,next,next);
DEC(edG.Text.numberOfLines);
edD.TextLoad;
IF edG.NoScreenUpdate = 0 THEN
g.ScrollRaster(edG.RPort,0,edG.YSize,edD.Col(0),
edD.Row(SHORT(edG.Text.line-edG.Text.topLine+1)),
edD.Col(edG.Columns)-1,edD.Row(edG.Rows)-1);
edD.TextRedisplayCurrentLine;
edD.TextDisplaySeg(edG.Rows-1,1);
END;
ELSE
edG.Rc := edE.cmdFailed;
END;
END doJoin;
PROCEDURE doSplit*;
VAR
len : INTEGER;
newLine : edG.LinePtr;
BEGIN
len := edG.LineBufferLen-edG.Text.pos;
edL.NewLine(newLine,len+edG.ChunkSize-(len MOD edG.ChunkSize));
IF edG.memoryFail IN edG.Status THEN
edG.Rc := edE.cmdSevere;
RETURN;
END;
str.Cut(edG.LineBuffer,edG.Text.pos,len,newLine(edG.Line).string^);
edG.LineBuffer[edG.Text.pos] := 0X;
len := SHORT(edG.Text.line-edG.Text.topLine);
g.SetAPen(edG.RPort,0);
g.RectFill(edG.RPort,edD.Col(0),edD.Row(len),
edG.XBase+edG.XPixs,edD.Row(len+1)-1);
InsertLine(newLine,TRUE);
doDown;
doUp;
END doSplit;
(*----------------------------------------------------------------------*)
(*
* GOTO [+/-]N
* GOTO BLOCK start of block
* GOTO START start of block
* GOTO END end of block
*)
PROCEDURE JumpToLine*(n: LONGINT);
BEGIN
IF n >= edG.Text.numberOfLines THEN
n := edG.Text.numberOfLines - 1; END;
IF (n >= 0) AND (n # edG.Text.line) THEN
edD.PutBackLine;
IF n = 0 THEN
edG.Text.actLinePtr :=edG.Text.lineList.head(edG.Line);
ELSIF n = edG.Text.numberOfLines-1 THEN
edG.Text.actLinePtr :=edG.Text.lineList.tail(edG.Line);
ELSIF n < edG.Text.line THEN
lst.GoBackwardNil(edG.Text.actLinePtr,edG.Text.line-n);
ELSE
lst.GoForwardNil(edG.Text.actLinePtr,n-edG.Text.line);
END;
edG.Text.line := n;
edD.TextLoad;
edD.TextSync;
EdGadgets.SetPropKnob;
END;
END JumpToLine;
PROCEDURE doGoto*;
VAR
n : LONGINT;
ok : BOOLEAN;
BEGIN
CASE CAP(edG.Arg[0][0]) OF
|"B","S": IF edG.Text = edG.Block.Owner THEN
edG.Text.line := edG.Block.SNum;
edG.Text.actLinePtr := edG.Block.mark.head;
ELSE
edG.Text.line := 0;
edG.Text.actLinePtr := edG.Text.lineList.head;
END;
|"E": IF edG.Text = edG.Block.Owner THEN
edG.Text.line := edG.Block.ENum;
edG.Text.actLinePtr := edG.Block.mark.tail;
ELSE
edG.Text.line := edG.Text.numberOfLines-1;
edG.Text.actLinePtr := edG.Text.lineList.tail;
END;
|ELSE IF NOT edL.StrToInt(edG.Arg[0],n) THEN
edG.Rc := edE.cmdError;
edL.Title(edG.BadArgument);
RETURN;
END;
IF edG.Arg[0][0] < "0" THEN (* mit Vorzeichen => relativ *)
n := n+edG.Text.line;
ELSE
DEC(n); (* intern bei Null anfangen *)
END;
JumpToLine(n);
RETURN;
END;
edD.TextSync;
END doGoto;
(*----------------------------------------------------------------------*)
(*
* PAGEUP
* PAGEDOWN
* PAGESET n (n = 0 to 100 for percentage of #rows to scroll, minimum 1)
* can be > 100.
*)
PROCEDURE doPage*;
VAR
n: INTEGER;
long: LONGINT;
BEGIN
IF pageSet IN edG.ArgSet THEN
IF edL.StrToInt(edG.Arg[0],long) THEN
PagePctg := ABS(SHORT(long));
ELSE
edL.Title(edG.BadArgument); edG.Rc := edE.cmdFailed;
END;
RETURN;
END;
n := edG.Rows * PagePctg DIV 100; IF n = 0 THEN n := 1; END;
IF pageUp IN edG.ArgSet THEN n := -n; END;
IF (n > 0) AND (edG.Text.topLine >= edG.Text.numberOfLines - edG.Rows) THEN
RETURN; END;
edD.PutBackLine;
INC(edG.Text.line,n); (* alle Werte per Hand setzen, da TextSync *)
INC(edG.Text.topLine,n); (* sonst nur einen halben Bildschirm scrollt! *)
IF edG.Text.line >= edG.Text.numberOfLines THEN
edG.Text.line := edG.Text.numberOfLines - 1;
ELSIF edG.Text.line < 0 THEN
edG.Text.line := 0;
END;
IF edG.Text.topLine >= edG.Text.numberOfLines THEN
edG.Text.topLine := edG.Text.numberOfLines - edG.Rows - 1;
ELSIF edG.Text.topLine < 0 THEN
edG.Text.topLine := 0;
END;
IF n < 0 THEN
lst.GoBackwardNil(edG.Text.actLinePtr,-n);
IF edG.Text.actLinePtr = NIL THEN
edG.Text.actLinePtr := edG.Text.lineList.head(edG.Line); END;
edG.Text.topLinePtr := edG.Text.actLinePtr;
lst.GoBackwardNil(edG.Text.topLinePtr,edG.Text.line-edG.Text.topLine);
ELSE
lst.GoForwardNil(edG.Text.actLinePtr,n);
IF edG.Text.actLinePtr = NIL THEN
edG.Text.actLinePtr := edG.Text.lineList.tail(edG.Line); END;
edG.Text.topLinePtr := edG.Text.actLinePtr;
lst.GoBackwardNil(edG.Text.topLinePtr,edG.Text.line-edG.Text.topLine);
END;
edD.TextLoad;
edD.TextSync;
IF NOT(edG.alreadyRedrawn IN edG.Status) THEN edD.TextRedisplay; END;
END doPage;
(*----------------------------------------------------------------------*)
PROCEDURE doPing*;
VAR
long: LONGINT;
BEGIN
IF edL.StrToInt(edG.Arg[0],long) AND (long<edG.NumPingPongs) THEN
edG.PingPong[long].txt := edG.Text;
edG.PingPong[long].line := edG.Text.line;
edG.PingPong[long].pos := edG.Text.pos;
edG.Rc := edE.cmdValid2; edL.Title(LineMarked);
ELSE
edG.Rc := edE.cmdFailed; edL.Title(PingOutOfRange);
END;
END doPing;
PROCEDURE doPong*;
VAR
long: LONGINT;
BEGIN
IF edL.StrToInt(edG.Arg[0],long) AND (long<edG.NumPingPongs)
AND (edG.PingPong[long].txt # NIL)
AND (edG.PingPong[long].line<edG.Text.numberOfLines) THEN
INC(edG.NoScreenUpdate);
edD.SwitchEdit(edG.PingPong[long].txt);
edG.Text.pos := edG.PingPong[long].pos;
DEC(edG.NoScreenUpdate);
JumpToLine(edG.PingPong[long].line);
ELSE
edG.Rc := edE.cmdFailed; edL.Title(PongRangeErrorOrNothingMarked);
END;
END doPong;
PROCEDURE ClearPingPongs;
VAR
i: INTEGER;
BEGIN
i := edG.NumPingPongs;
REPEAT
DEC(i);
edG.PingPong[i].txt := NIL;
UNTIL i = 0;
END ClearPingPongs;
(*-------------------------------------------------------------------------*)
(* schreibt <text> in den Buffer und auf den Scrren, beachtet InsertMode *)
PROCEDURE TextWrite*(text: edG.StringPtr);
VAR
len,i : INTEGER;
buf : edG.StringPtr;
BEGIN
len := str.Length(text^);
IF edG.LineBufferLen+len >= edG.MaxLineLength-1 THEN
edD.TextLoad;
edD.TextSync;
END;
IF NOT (edG.insertMode IN edG.Text.status) THEN
IF (edG.Text.pos+len >= edG.MaxLineLength-1) THEN
edL.Title(LineTooLong); edG.Rc := edE.cmdFailed;
RETURN;
END;
buf := sys.ADR(edG.LineBuffer[edG.Text.pos]);
e.CopyMem(text^,buf^,len);
IF (edG.Text.pos+len > edG.LineBufferLen) THEN
edG.LineBufferLen := edG.Text.pos+len;
edG.LineBuffer[edG.LineBufferLen] := 0X;
END;
ELSE
IF (edG.LineBufferLen+len >= edG.MaxLineLength-1) THEN
edL.Title(LineTooLong); edG.Rc := edE.cmdFailed;
RETURN;
END;
str.Insert(edG.LineBuffer,edG.Text.pos,text^);
INC(edG.LineBufferLen,len);
IF (len < edG.Columns - (edG.Text.pos-edG.Text.topPos)) THEN
edD.FastScrollRaster(-len*edG.XSize,0,
edD.Col(edG.Text.pos-edG.Text.topPos),
edD.Row(SHORT(edG.Text.line-edG.Text.topLine)),edD.Col(edG.Columns),
edD.Row(SHORT(edG.Text.line-edG.Text.topLine+1))-1);
END;
END; (* IF NOT InsertMode *)
IF (edG.Text.pos-edG.Text.topPos+len > edG.Columns) THEN
i := edG.Columns-edG.Text.pos+edG.Text.topPos;
ELSE
i := len;
END;
edD.SetPen(edG.Text.line);
g.Move(edG.RPort,edD.ColT(edG.Text.pos-edG.Text.topPos),
edD.RowT(SHORT(edG.Text.line-edG.Text.topLine)));
g.Text(edG.RPort,text^,i);
INC(edG.Text.pos,len);
IF (edG.Text.pos-edG.Text.topPos >= edG.Columns) THEN
edD.TextSync; END;
IF NOT (edG.commLineMode IN edG.Status) AND (edG.NoScreenUpdate = 0)
AND (edG.wordWrap IN edG.Text.status) THEN
doReformat; END;
END TextWrite;
(*-------------------------------------------------------------------------*)
(*
* rfmtParag : force reformat entire paragraph
* ~rfmtParag : only until line equalizes (from TextWrite())
*
* What is a paragraph? A paragraph ends whenever the left justification
* gets larger, or on a blank line.
*)
(* $Debug= *)
PROCEDURE doReformat*;
VAR
string: edG.StringPtr;
lnsc, fnst, fnsc: INTEGER;
column: INTEGER;
srow, crow, erow: LONGINT;
cptr: edG.LinePtr; (* origin line *)
dins: INTEGER; (* relative insert lines/delete lines *)
moded: BOOLEAN; (* any modifications done at all? *)
checked: BOOLEAN; (* for cursor positioning. *)
nlok: BOOLEAN;
i, indent: INTEGER;
BEGIN
column := edG.Text.pos;
srow := edG.Text.line; erow := srow; crow := srow;
cptr := edG.Text.actLinePtr;
dins := 0; moded := FALSE; checked := FALSE;
IF (edG.Text.margin = 0) THEN edG.Text.margin := 75; END;
INC(edG.NoScreenUpdate);
LOOP
string := edG.Text.actLinePtr.next(edG.Line).string;
fnsc := edL.FirstNoSpace(sys.ADR(edG.LineBuffer));
fnst := edL.FirstNoSpace(string);
nlok := (edG.Text.line + 1 < edG.Text.numberOfLines) AND (fnsc >= fnst);
IF string[0] = 0X THEN
nlok := FALSE; END;
lnsc := edL.LastNoSpace(sys.ADR(edG.LineBuffer));
IF (lnsc < edG.Text.margin) THEN
(* space at end of line for margin-lnsc-2 letter word *)
IF NOT nlok THEN (* but no more data to joinup *)
EXIT; END; (* done *)
IF (edG.Text.margin-lnsc-2 >= edL.WordLen(sys.ADR(string[fnst]))) THEN
edG.Text.pos := 0;
edG.LineBufferLen := edL.LastNoSpace(sys.ADR(edG.LineBuffer));
IF (edG.LineBuffer[edG.LineBufferLen] # 0X) THEN
INC(edG.LineBufferLen); END;
moded := TRUE;
DEC(dins);
doJoin;
IF edG.Rc >= edE.cmdFailed THEN
INC(dins);
edL.Title(edG.ErrorMarginOver124);
EXIT; (* stop reformating *)
END;
ELSE
IF NOT (rfmtParag IN edG.ArgSet) THEN (* if couldn't mod line, and *)
EXIT; END; (* TextWrite, don't update any more *)
doDown;
erow := edG.Text.line;
END;
ELSE (* no space, need to split *)
LOOP (* find start of prev word *)
WHILE (lnsc # 0) & (edG.LineBuffer[lnsc] # ' ') DO
DEC(lnsc); END;
IF (lnsc < edG.Text.margin) THEN
EXIT; END;
DEC(lnsc); (* edG.Text.margin >= 1 !! *)
END;
IF (lnsc # 0) THEN (* ok to split at word *)
INC(lnsc);
INC(dins);
edG.Text.pos := lnsc;
doSplit; (* Split at point LNSC *)
edG.Text.pos := 0; (* avoid FillUpSpaces *)
doDown; (* must insert proper amount? *)
IF nlok THEN
indent := fnst;
ELSE
indent := fnsc;
END;
IF NOT checked THEN
checked := TRUE;
IF (lnsc <= column) THEN (* if split before cursor *)
column := column - edG.Text.pos + indent;
cptr := cptr.next(edG.Line); INC(crow);
END;
END;
IF (indent # 0) AND (edG.LineBufferLen + indent < 253) THEN
i := str.Length(edG.LineBuffer)+1;
REPEAT
edG.LineBuffer[indent+i] := edG.LineBuffer[i];
DEC(i);
UNTIL i < 0;
INC(edG.LineBufferLen,indent);
REPEAT
DEC(indent);
edG.LineBuffer[indent] := " ";
UNTIL indent = 0;
END;
erow := edG.Text.line;
ELSE
IF NOT (rfmtParag IN edG.ArgSet) THEN EXIT; END;
doDown;
END;
END;
END; (* LOOP *)
IF (column < 0) OR (column > 200) THEN
column := 0; END;
edD.PutBackLine;
edG.Text.actLinePtr := cptr;
edG.Text.line := crow;
edG.Text.pos := column;
DEC(edG.NoScreenUpdate);
edD.TextLoad;
edD.TextSync;
IF (dins # 0) OR (srow >= edG.Text.numberOfLines)
OR (srow < edG.Text.topLine) OR (srow >= edG.Text.topLine + edG.Rows) THEN
IF (srow >= edG.Text.numberOfLines) THEN
srow := edG.Text.numberOfLines - 1;
END;
IF NOT (edG.alreadyRedrawn IN edG.Status) THEN
edD.TextRedisplay; END;
ELSE
IF (erow = srow) AND moded THEN
edD.TextRedisplayCurrentLine;
ELSIF NOT (edG.alreadyRedrawn IN edG.Status) THEN
INC(erow);
IF (erow - edG.Text.topLine > edG.Rows) THEN
erow := edG.Text.topLine + edG.Rows; END;
g.SetAPen(edG.RPort, 0);
g.RectFill(edG.RPort, edD.Col(0), edD.Row(SHORT(srow - edG.Text.topLine)),
edG.XBase+edG.XPixs, edD.Row(SHORT(erow - edG.Text.topLine))-1);
g.SetAPen(edG.RPort, 1);
edD.TextDisplaySeg(SHORT(srow-edG.Text.topLine),SHORT(erow-srow));
END;
END;
edG.Text.pos := column;
edL.FillUpSpaces;
END doReformat;
(* $Debug-*)
(*-----------------------------------------------------------------------*)
BEGIN
PagePctg := 80;
ClearPingPongs;
END EdMovement.